#pragma once 

class ZUC {

private:
    unsigned int LFSR_S[16];
    unsigned int F_R1;
    unsigned int F_R2;
    unsigned int BRC_X[4];
    static unsigned char S0[256];
    static unsigned char S1[256];
    static unsigned int EK_d[16];
    unsigned int AddM(unsigned int a, unsigned int b);
    void LFSRWithInitializationMode(unsigned int u);
    void LFSRWithWorkMode();
    void BitReorganization();
    unsigned int L1(unsigned int X);
    unsigned int L2(unsigned int X);
    unsigned int F(void);
    
public:
    ZUC() {};
    ZUC(unsigned char *k, unsigned char *iv) {
        Initialization(k, iv);
    }
    void Initialization(unsigned char *k, unsigned char *iv);
    void GenerateKeyStream(unsigned int *pKeyStream, unsigned int KeyStreamLen);
};

    


